home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 264_01 / nrocmd.c < prev    next >
Text File  |  1980-01-01  |  12KB  |  735 lines

  1. /*
  2.  *    Command processor for NRO text processor
  3.  *
  4.  *    Stephen L. Browning
  5.  *    5723 North Parker Avenue
  6.  *    Indianapolis, Indiana 46220
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <ctype.h>
  11. #include "nro.h"
  12. #include "nrocom.c"
  13.  
  14. comand(p)
  15. char *p;
  16. {
  17.     int ct, val;
  18.     int spval;
  19.     int index;
  20.     char argtyp;
  21.     char name[MAXLINE];
  22.     char macexp[MXMLEN];
  23.     char *skipwd(), *skipbl();
  24.  
  25.     ct = comtyp(p,macexp);
  26.     if (ct == UNKNOWN)
  27.     {
  28.         fprintf(stderr, "nro: unrecognized command %s\n",p);
  29.         return;
  30.     }
  31.     expesc(p,name);
  32.     val = getval(p,&argtyp);
  33.     switch (ct)
  34.     {
  35.     case BO: /* bold face */
  36.         set(&dc.boval,val,argtyp,1,0,HUGE);
  37.         dc.cuval = dc.ulval = 0;
  38.         break;
  39.  
  40.     case BP: /* begin page */
  41.         if(pg.lineno > 0)
  42.             space(HUGE);
  43.         set(&pg.curpag,val,argtyp,pg.curpag+1,-HUGE,HUGE);
  44.         pg.newpag = pg.curpag;
  45.         break;
  46.  
  47.     case BR: /* break */
  48.         brk();
  49.         break;
  50.  
  51.     case BS: /* backspaces in output */
  52.         set(&dc.bsflg,val,argtyp,1,0,1);
  53.         break;
  54.  
  55.     case CC: /* command character */
  56.         if (argtyp == '\r' || argtyp == '\n')
  57.             dc.cmdchr = '.';
  58.         else
  59.             dc.cmdchr = argtyp;
  60.         break;
  61.  
  62.     case CE: /* center */
  63.         brk();
  64.         set(&dc.ceval,val,argtyp,1,0,HUGE);
  65.         break;
  66.  
  67.     case CU: /* continuous underline */
  68.         set(&dc.cuval,val,argtyp,1,0,HUGE);
  69.         dc.ulval = dc.boval = 0;
  70.         break;
  71.  
  72.     case DE: /* define macro */
  73.         defmac(p,sofile[dc.flevel]);
  74.         break;
  75.  
  76.     case EF: /* even footer */
  77.         gettl(p,pg.efoot,&pg.eflim[0]);
  78.         break;
  79.  
  80.     case EH: /* even header */
  81.         gettl(p,pg.ehead,&pg.ehlim[0]);
  82.         break;
  83.  
  84.     case EN: /* end macro definition */
  85.         fprintf(stderr, "***nro: missing .de command\n");
  86.         break;
  87.  
  88.     case FI: /* fill */
  89.         brk();
  90.         dc.fill = YES;
  91.         break;
  92.  
  93.     case FO: /* footer */
  94.         gettl(p,pg.efoot,&pg.eflim[0]);
  95.         gettl(p,pg.ofoot,&pg.oflim[0]);
  96.         break;
  97.  
  98.     case HE: /* header */
  99.         gettl(p,pg.ehead,&pg.ehlim[0]);
  100.         gettl(p,pg.ohead,&pg.ohlim[0]);
  101.         break;
  102.  
  103.     case IN: /* indenting */
  104.         set(&dc.inval,val,argtyp,0,0,dc.rmval-1);
  105.         dc.tival = dc.inval;
  106.         break;
  107.  
  108.     case JU: /* justify */
  109.         dc.juval = YES;
  110.         break;
  111.  
  112.     case LS: /* line spacing */
  113.         set(&dc.lsval,val,argtyp,1,1,HUGE);
  114.         break;
  115.  
  116.     case M1: /* set topmost margin */
  117.         set(&pg.m1val,val,argtyp,2,0,HUGE);
  118.         break;
  119.  
  120.     case M2: /* set second top margin */
  121.         set(&pg.m2val,val,argtyp,2,0,HUGE);
  122.         break;
  123.  
  124.     case M3: /* set first bottom margin */
  125.         set(&pg.m3val,val,argtyp,2,0,HUGE);
  126.         pg.bottom = pg.plval - pg.m4val - pg.m3val;
  127.         break;
  128.  
  129.     case M4: /* set bottom-most margin */
  130.         set(&pg.m4val,val,argtyp,2,0,HUGE);
  131.         pg.bottom = pg.plval - pg.m4val - pg.m3val;
  132.         break;
  133.  
  134.     case MACRO: /* macro expansion */
  135.         maceval(p,macexp);
  136.         break;
  137.  
  138.     case NE: /* need n lines */
  139.         brk();
  140.         if ((pg.bottom-pg.lineno+1) < (val*dc.lsval))
  141.         {
  142.             space(HUGE);
  143.         }
  144.         break;
  145.  
  146.     case NF: /* no fill */
  147.         brk();
  148.         dc.fill = NO;
  149.         break;
  150.  
  151.     case NJ: /* no justify */
  152.         dc.juval = NO;
  153.         break;
  154.  
  155.     case NR: /* set number register */
  156.         p = skipwd(p);
  157.         p = skipbl(p);
  158.         if (!isalpha(*p))
  159.         {
  160.             fprintf(stderr, "nro: invalid or missing number register name\n");
  161.         }
  162.         else
  163.         {
  164.             index = tolower(*p) - 'a';
  165.             p = skipwd(p);
  166.             val = getval(p,&argtyp);
  167.             set(&dc.nr[index],val,argtyp,0,-HUGE,HUGE);
  168.         }
  169.         break;
  170.  
  171.     case OF: /* odd footer */
  172.         gettl(p,pg.ofoot,&pg.oflim[0]);
  173.         break;
  174.  
  175.     case OH: /* odd header */
  176.         gettl(p,pg.ohead,&pg.ohlim[0]);
  177.         break;
  178.  
  179.     case PC: /* page number character */
  180.         if (argtyp == '\r' || argtyp == '\n')
  181.             dc.pgchr = '\0';
  182.         else
  183.             dc.pgchr = argtyp;
  184.         break;
  185.  
  186.     case PL: /* page length */
  187.         set(&pg.plval,val,argtyp,PAGELEN,
  188.             pg.m1val+pg.m2val+pg.m3val+pg.m4val+1,HUGE);
  189.         pg.bottom = pg.plval - pg.m3val - pg.m4val;
  190.         break;
  191.  
  192.     case PO: /* page offset */
  193.         set(&pg.offset,val,argtyp,0,0,HUGE);
  194.         break;
  195.  
  196.     case RM: /* right margin */
  197.         set(&dc.rmval,val,argtyp,PAGEWIDTH,dc.tival+1,HUGE);
  198.         break;
  199.  
  200.     case SO: /* source file */
  201.         p = skipwd(p);
  202.         p = skipbl(p);
  203.         if (getwrd(p,name) == 0) break;
  204.         if (dc.flevel+1 >= NFILES)
  205.         {
  206.             fprintf(stderr, "nro: .so commands nested too deeply\n");
  207.             exit(-1);
  208.         }
  209.         if((sofile[dc.flevel+1] = fopen(name, "r")) == (FILE *)0)
  210.         {
  211.             printf("***nro: unable to open %s\n",name);
  212.             exit(-1);
  213.         }
  214.         ++dc.flevel;
  215.         break;
  216.  
  217.     case SP: /* space */
  218.         set(&spval,val,argtyp,1,0,HUGE);
  219.         space(spval);
  220.         break;
  221.  
  222.     case TI: /* temporary indent */
  223.         brk();
  224.         set(&dc.tival,val,argtyp,0,0,dc.rmval);
  225.         break;
  226.  
  227.     case UL: /* underline */
  228.         set(&dc.ulval,val,argtyp,0,1,HUGE);
  229.         dc.cuval = dc.boval = 0;
  230.         break;
  231.     }
  232. }
  233.  
  234.  
  235.  
  236. /*
  237.  *    convert ascii character to decimal.
  238.  */
  239.  
  240. atod(c)
  241. char c;
  242. {
  243.     return(((c < '0') || (c > '9')) ? -1 : c-'0');
  244. }
  245.  
  246.  
  247.  
  248. /*
  249.  *    end current filled line
  250.  */
  251.  
  252. brk()
  253. {
  254.     if(co.outp > 0)
  255.     {
  256.         co.outbuf[co.outp] = '\r';
  257.         co.outbuf[co.outp + 1] = '\n';
  258.         co.outbuf[co.outp + 2] = '\0';
  259.         put(co.outbuf);
  260.     }
  261.     co.outp = 0;
  262.     co.outw = 0;
  263.     co.outwds = 0;
  264. }
  265.  
  266.  
  267. /*
  268.  *    Collect macro definition from input stream
  269.  */
  270.  
  271. colmac(p,d,i)
  272. char *p, d[];
  273. int i;
  274. {
  275.     while (*p != '\0')
  276.     {
  277.         if (i >= MXMLEN-1)
  278.         {
  279.             d[i-1] = '\0';
  280.             return(ERR);
  281.         }
  282.         d[i++] = *p++;
  283.     }
  284.     d[i] = '\0';
  285.     return(i);
  286. }
  287.  
  288.  
  289.  
  290.  
  291. /*
  292.  *    decodes nro command and returns its associated
  293.  *    value.
  294.  */
  295.  
  296. comtyp(p,m)
  297. char *p;
  298. char *m;
  299. {
  300.     char c1, c2;
  301.     char macnam[MNLEN];
  302.     char *s;
  303.  
  304.     p++;
  305.     /*
  306.     *    First check to see if the command is a macro.
  307.     *    If it is, truncate to two characters and return
  308.     *    expansion in m.  Note that upper and lower case
  309.     *    characters are handled differently for macro names,
  310.     *    but not for normal command names.
  311.     */
  312.     getwrd(p,macnam);
  313.     macnam[2] = '\0';
  314.     if ((s = getmac(macnam)) != NULL)
  315.     {
  316.         strcpy(m,s);
  317.         return(MACRO);
  318.     }
  319.     c1 = tolower(*p);
  320.     p++;
  321.     c2 = tolower(*p);
  322.     if (c1 == 'b' && c2 == 'o') return(BO);
  323.     if (c1 == 'b' && c2 == 'p') return(BP);
  324.     if (c1 == 'b' && c2 == 'r') return(BR);
  325.     if (c1 == 'b' && c2 == 's') return(BS);
  326.     if (c1 == 'c' && c2 == 'c') return(CC);
  327.     if (c1 == 'c' && c2 == 'e') return(CE);
  328.     if (c1 == 'c' && c2 == 'u') return(CU);
  329.     if (c1 == 'd' && c2 == 'e') return(DE);
  330.     if (c1 == 'e' && c2 == 'f') return(EF);
  331.     if (c1 == 'e' && c2 == 'h') return(EH);
  332.     if (c1 == 'e' && c2 == 'n') return(EN);
  333.     if (c1 == 'f' && c2 == 'i') return(FI);
  334.     if (c1 == 'f' && c2 == 'o') return(FO);
  335.     if (c1 == 'h' && c2 == 'e') return(HE);
  336.     if (c1 == 'i' && c2 == 'n') return(IN);
  337.     if (c1 == 'j' && c2 == 'u') return(JU);
  338.     if (c1 == 'l' && c2 == 's') return(LS);
  339.     if (c1 == 'm' && c2 == '1') return(M1);
  340.     if (c1 == 'm' && c2 == '2') return(M2);
  341.     if (c1 == 'm' && c2 == '3') return(M3);
  342.     if (c1 == 'm' && c2 == '4') return(M4);
  343.     if (c1 == 'n' && c2 == 'e') return(NE);
  344.     if (c1 == 'n' && c2 == 'f') return(NF);
  345.     if (c1 == 'n' && c2 == 'j') return(NJ);
  346.     if (c1 == 'n' && c2 == 'r') return(NR);
  347.     if (c1 == 'o' && c2 == 'f') return(OF);
  348.     if (c1 == 'o' && c2 == 'h') return(OH);
  349.     if (c1 == 'p' && c2 == 'c') return(PC);
  350.     if (c1 == 'p' && c2 == 'l') return(PL);
  351.     if (c1 == 'p' && c2 == 'o') return(PO);
  352.     if (c1 == 'r' && c2 == 'm') return(RM);
  353.     if (c1 == 's' && c2 == 'o') return(SO);
  354.     if (c1 == 's' && c2 == 'p') return(SP);
  355.     if (c1 == 't' && c2 == 'i') return(TI);
  356.     if (c1 == 'u' && c2 == 'l') return(UL);
  357.     return(UNKNOWN);
  358. }
  359.  
  360.  
  361.  
  362. /*
  363.  *    convert string to decimal.
  364.  *    processes only positive values.
  365.  */
  366.  
  367. ctod(p)
  368. char *p;
  369. {
  370.     int val, d;
  371.  
  372.     val = 0;
  373.     while(*p != '\0')
  374.     {
  375.         d = atod(*p++);
  376.         if(d == -1) return(val);
  377.         val = 10 * val + d;
  378.     }
  379.     return(val);
  380. }
  381.  
  382.  
  383. /*
  384.  *    Define a macro
  385.  */
  386.  
  387. defmac(p,infp)
  388. char *p;
  389. FILE *infp;
  390. {
  391.     int i;
  392.     char name[MNLEN];
  393.     char defn[MXMLEN];
  394.     char *q;
  395.  
  396.     q = skipwd(p);
  397.     q = skipbl(q);
  398.     i = getwrd(q,name);
  399.     if (!isalpha(*name))
  400.     {
  401.         fprintf("nro: missing or illegal macro definition name\n");
  402.         exit(-1);
  403.     }
  404.     if (i > 2) name[2] = '\0';
  405.     i = 0;
  406.     while (getlin(p,infp) != EOF)
  407.     {
  408.         if (p[0] == dc.cmdchr && tolower(p[1]) == 'e' && tolower(p[2]) == 'n')
  409.         {
  410.             break;
  411.         }
  412.         if ((i = colmac(p,defn,i)) == ERR)
  413.         {
  414.             fprintf("nro: macro definition too long\n");
  415.             exit(-1);
  416.         }
  417.     }
  418.     if (putmac(name,defn) == ERR)
  419.     {
  420.         fprintf("nro: macro def